package com.liu.producer.codec;


import com.liu.agreement.Agreement;
import com.liu.message.MessageTypeEnum;
import com.liu.producer.resolver.MessageResolverProvider;
import com.liu.serialization.Serialization;
import com.liu.serialization.SerializationProvider;
import com.liu.serialization.SerializationTypeEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @param
 * @BelongsProject: MessageQueueDEMO
 * @BelongsPackage: com.liu.producer.codec
 * @author: L
 * @Date: 2023/10/14 23:22
 * @return
 */
@Slf4j
public class MessageCodec extends MessageToMessageCodec<ByteBuf, Agreement> {

    @Override
    protected void encode(ChannelHandlerContext ctx, Agreement agreement, List<Object> out) throws Exception {
        log.info("---->encode");
        ByteBuf buffer = ctx.alloc().buffer();
        // 魔数 4
        buffer.writeInt(agreement.getMagicNumber());
        // 版本号 1
        buffer.writeByte(agreement.getVersion());
        // 消息的类型 1
        buffer.writeByte(agreement.getMessageType().getType());
        // 序列化类型 1
        SerializationTypeEnum serializationType = agreement.getSerializationType();
        buffer.writeByte(serializationType.getType());
        // 消息主题 4
        buffer.writeBytes(agreement.getTopic());
        // 消息ID 8
        buffer.writeLong(agreement.getMessageID());
        // 消息体长度固定 4
        // 消息体处理
        if (null == agreement.getBody()) {
            // 消息体长度
            buffer.writeInt(0);
        } else {
            // 获取对应序列化器
            Serialization serialization = SerializationProvider.getSerialization(serializationType);
            byte[] bytes = serialization.serialization(agreement.getBody());
            // 消息体长度
            buffer.writeInt(bytes.length);
            buffer.writeBytes(bytes);
        }
        out.add(buffer);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) {
        log.info("---->decode");
        // 魔数
        int magicNumber = byteBuf.readInt();
        // 版本
        byte version = byteBuf.readByte();
        // 消息类型
        MessageTypeEnum messageType = MessageTypeEnum.get(byteBuf.readByte());
        // 序列化类型
        SerializationTypeEnum serializationType = SerializationTypeEnum.get(byteBuf.readByte());
        // 消息主题
        byte[] topic = new byte[4];
        byteBuf.readBytes(topic);
        // 消息ID
        long messageID = byteBuf.readLong();
        // 消息体长度
        int bodyLength = byteBuf.readInt();
        if (bodyLength<=0){
            return;
        }
        // 消息体 返回状态码
        byte[] body = new byte[bodyLength];
        byteBuf.readBytes(body);
        Agreement agreement = new Agreement(messageType, serializationType,body);
        // 解析请求体
        Object object= MessageResolverProvider.resovler(agreement);
        out.add(object);
    }
}
